package com.cainiao.dao;

import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.util.Properties;

/**
 * @author shkstart
 * @create 2021-04-23 13:48
 * 多插件开发
 */
@Intercepts({
        @Signature(type = StatementHandler.class, method = "parameterize", args = java.sql.Statement.class)
})
public class MySecondPlugin implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("MySecondPlugin intercept:拦截方法:" + invocation.getMethod());
        //动态的改变一下sql运行的参数，以前查询1号员工，实际从数据库查询3号员工
        Object target = invocation.getTarget();
        System.out.println("当前拦截到的对象:" + target);
        /*StatementHandler=》RoutingStatementHandler。根据类型创建PreparedStatementHandler
         =》PreparedStatementHandler借助parameterHandler=》parameterHandler我们用的都是DefaultParameterHandler
         =》DefaultParameterHandler.parameterObject
         */
        //拿到：StatementHandler=》PreparedStatementHandler==》parameterObject
        //使用SystemMetaObject.forObject(),拿到target的元数据
        MetaObject metaObject = SystemMetaObject.forObject(target);
        //获取sql参数值
        Object value = metaObject.getValue("parameterHandler.parameterObject");
        System.out.println("sql语句用的参数是:" + value);
        //修改完sql语句要用的参数
        metaObject.setValue("parameterHandler.parameterObject", 3);

        //执行方法
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object o) {
        System.out.println("MySecondPlugin plugin:包装的对象是:" + o);
        //我们可以借助Plugin的wrap方法来使用当前类Interceptor包装我们目标对象
        return Plugin.wrap(o, this);

    }


    @Override
    public void setProperties(Properties properties) {

    }
}
